﻿using GiveMeMenu.Interface.ServiceProvider;
using GiveMeMenu.Interface.ServiceProvider.ObjectModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GiveMeMenu.ServiceProvider.DataAccess;
using GiveMeMenu.Common.Cache;

namespace GiveMeMenu.ServiceProvider.ServiceProvider
{
    /// <summary>
    /// GMM service provider
    /// </summary>
    public class GMMServiceProvider : IGMMServiceProvider
    {
        IGMMServiceAgent ServiceAgent;
        PipeNode<Dish> DishCache = new PipeNode<Dish>();
        PipeNode<LuTable> LuTableCache = new PipeNode<LuTable>();
        PipeNode<Dish> DishTodayCache = new PipeNode<Dish>();
        PipeNode<LuTypeDish> LuTypeDishCache = new PipeNode<LuTypeDish>();
        KeyEndNode<int, OrderInformation> OrderInformationByOrderIdCache = new KeyEndNode<int, OrderInformation>();

        public GMMServiceProvider(IGMMServiceAgent serviceAgent)
        {
            if (serviceAgent != null)
            {
                ServiceAgent = serviceAgent;
            }
            else
            {
                throw new ArgumentNullException("IGMMServiceAgent is nullable");
            }
        }

        #region IGMMServiceProvider Members

        /// <summary>
        /// Gets all dishs.
        /// </summary>
        /// <returns></returns>
        public IList<Dish> GetAllDishes()
        {
            IList<Dish> result = DishCache.Get();
            if (result == null)
            {
                IList<Dish> dishes = ServiceAgent.GetAllDishes();
                DishCache.Add(dishes);
                return dishes;
            }
            else {
                return result;
            }
        }

        /// <summary>
        /// Removes the order.
        /// </summary>
        /// <param name="OId">The O id.</param>
        /// <returns></returns>
        public bool RemoveOrder(int OId)
        {
            return ServiceAgent.RemoveOrder(OId);
        }

        /// <summary>
        /// Removes the order information.
        /// </summary>
        /// <param name="OId">The O id.</param>
        /// <returns></returns>
        public bool RemoveOrderInformation(int OId)
        {
            return ServiceAgent.RemoveOrderInformation(OId);
        }

        /// <summary>
        /// Gets the dish today.
        /// </summary>
        /// <returns></returns>
        public IList<Dish> GetDishToday()
        {
            IList<Dish> result = DishTodayCache.Get();
            if (result == null)
            {
                IList<Dish> dishes = ServiceAgent.GetDishToday();
                DishTodayCache.Add(dishes);
                return dishes;
            }
            else
            {
                return result;
            }
        }

        /// <summary>
        /// Adds the dish.
        /// </summary>
        /// <param name="typeId">The type id.</param>
        /// <param name="name">The name.</param>
        /// <param name="price">The price.</param>
        /// <param name="description">The description.</param>
        /// <param name="orderDate">The order date.</param>
        /// <param name="discount">The discount.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool AddDish(Dish dish)
        {
            bool result =  ServiceAgent.AddDish(dish);
            if (result)
            {
                DishCache.ClearCache();
            }
            return result;
        }

        /// <summary>
        /// Adds the order.
        /// </summary>
        /// <param name="tableId"></param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool AddOrder(Order order)
        {
            return ServiceAgent.AddOrder(order);
        }

        /// <summary>
        /// Adds the order information.
        /// </summary>
        /// <param name="orderId"></param>
        /// <param name="dishId">The dish id.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool AddOrderInformation(OrderInformation info)
        {
            return ServiceAgent.AddOrderInformation(info);
        }

        /// <summary>
        /// Addlus the table.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool AddluTable(LuTable luTable)
        {
            bool result = ServiceAgent.AddluTable(luTable);
            if (result)
            {
                LuTableCache.ClearCache();
            }
            return result;
        }

        /// <summary>
        /// Addlus the type dish.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool AddluTypeDish(LuTypeDish luTypeDish)
        {
            bool result = ServiceAgent.AddluTypeDish(luTypeDish);
            if (result)
            {
                LuTypeDishCache.ClearCache();
            }
            return result;
        }

        /// <summary>
        /// Getlus the tables.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public IList<LuTable> GetluTables()
        {
            IList<LuTable> luTables =  ServiceAgent.GetluTables();
            LuTableCache.Add(luTables);
            return luTables;
        }

        /// <summary>
        /// Getlus the type dish.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public IList<LuTypeDish> GetluTypeDish()
        {
            IList<LuTypeDish> luTypeDishes = ServiceAgent.GetluTypeDish();
            LuTypeDishCache.Add(luTypeDishes);
            return luTypeDishes;
        }

        /// <summary>
        /// Gets the order information by order id.
        /// </summary>
        /// <param name="orderOId">The order O id.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public IList<OrderInformation> GetOrderInformationByOrderId(int orderOId)
        {
            IList<OrderInformation> orderInformations = OrderInformationByOrderIdCache.Get(orderOId);
            if (orderInformations == null)
            {
                orderInformations = ServiceAgent.GetOrderInformationByOrderId(orderOId);
                OrderInformationByOrderIdCache.Add(orderOId, orderInformations);
            }
            return orderInformations;
        }

        /// <summary>
        /// Removes the dish.
        /// </summary>
        /// <param name="oId">The o id.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool RemoveDish(int oId)
        {
            bool result = ServiceAgent.RemoveDish(oId);
            if (result)
            {
                DishCache.ClearCache();
            }
            return result;
        }

        /// <summary>
        /// Removelus the table.
        /// </summary>
        /// <param name="oId">The o id.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool RemoveluTable(int oId)
        {
            bool result = ServiceAgent.RemoveluTable(oId);
            if (result)
            {
                LuTableCache.ClearCache();
            }
            return result;
        }

        /// <summary>
        /// Removelus the type dish.
        /// </summary>
        /// <param name="oId">The o id.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool RemoveluTypeDish(int oId)
        {
            bool result = ServiceAgent.RemoveluTypeDish(oId);
            if (result)
            {
                LuTypeDishCache.ClearCache();
            }
            return result;
        }


        /// <summary>
        /// Updates the dish.
        /// </summary>
        /// <param name="dish"></param>
        /// <returns></returns>
        public bool UpdateDish(Dish dish)
        {
            bool result = ServiceAgent.UpdateDish(dish);
            if (result)
            {
                DishCache.ClearCache();
            }
            return result;
        }


        /// <summary>
        /// Updatelus the table.
        /// </summary>
        /// <param name="luTable"></param>
        /// <returns></returns>
        public bool UpdateluTable(LuTable luTable)
        {
            bool result = ServiceAgent.UpdateluTable(luTable);
            if (result)
            {
                LuTableCache.ClearCache();
            }
            return result;
        }

        /// <summary>
        /// Updatelus the type dish.
        /// </summary>
        /// <param name="oId"></param>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool UpdateluTypeDish(LuTypeDish luTypeDish)
        {
            bool result = ServiceAgent.UpdateluTypeDish(luTypeDish);
            if (result)
            {
                LuTypeDishCache.ClearCache();
            }
            return result;
        }

        /// <summary>
        /// Updates the order.
        /// </summary>
        /// <param name="oId">The o id.</param>
        /// <param name="tableId">The table id.</param>
        /// <param name="confirmOrder">if set to <c>true</c> [confirm order].</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public bool UpdateOrder(Order order)
        {
            return ServiceAgent.UpdateOrder(order);
        }

        #endregion
    }
}
